﻿using HK.Core.GUIEx.Protocol.Attribute;
using HK.Editor.Common;
using HK.Editor.GUIEx.Protocol.Drawer;
using HK.Editor.Utils;
using UnityEditor;
using UnityEngine;
using HLogger = HK.Core.Logs.Logger;

namespace HK.Editor.GUIEx.Drawer
{
    /// <summary>
    /// 可序列化文件头部编辑器
    /// </summary>
    public class SAssetHeaderDrawer : GUIDiyDrawer, ISAssetHeaderDrawer
    {

#region Create

        /// <summary>
        /// 创建头部Drawer
        /// </summary>
        /// <param name="iSelf">自身Property</param>
        /// <param name="iStatic">静态标志位</param>
        /// <param name="iPath">路径</param>
        /// <returns>头部Drawer</returns>
        public static ISAssetHeaderDrawer Create(SerializedProperty iSelf, bool iStatic, string iPath)
        {
            var header = new SAssetHeaderDrawer { Static = iStatic, Path = iPath };

            // 初始化
            if (!header.InitSerializedProperties(iSelf))
            {
                HLogger.Error("SAssetHeaderDrawer::Create():InitSerializedProperties() Failed!");
                return null;
            }
            return header;
        }

#endregion
        
        /// <summary>
        /// 保护构造函数
        /// </summary>
        protected SAssetHeaderDrawer() {}

        /// <summary>
        /// 静态文件标志位
        /// </summary>
        public bool Static { get; private set; } = false;

        /// <summary>
        /// 路径
        /// </summary>
        public string Path { get; private set; } = null;

#region Size&Rect
        
        /// <summary>
        /// 取得高度
        /// <para>* 包含子节点及其展开/不展开的实际高度</para>
        /// </summary>
        /// <returns>高度</returns>
        public override float CalcTotalHeight()
        {
            TotalHeight = HeaderHeight;
            if (null != SelfProperty && SelfProperty.isExpanded)
            {
                TotalHeight += GetPropertiesTotalHeight(SelfProperty);
            }

            // 静态文件标志位
            TotalHeight += SingleLineHeight;
            // 路径
            TotalHeight += SingleLineHeight;

            TotalHeight -= VerticalSpacing * 2;
            return TotalHeight;
        }

#endregion

#region SerializedProperty

        /// <summary>
        /// 序列化Property - 版本号
        /// </summary>
        protected SerializedProperty VersionProperty { get; private set; } = null;

        /// <summary>
        /// 序列化Property - 创建日期
        /// </summary>
        protected SerializedProperty CreateProperty { get; private set; } = null;

        /// <summary>
        /// 序列化Property - 更新日期
        /// </summary>
        protected SerializedProperty UpdateProperty { get; private set; } = null;
        
        /// <summary>
        /// 初始化序列化Property信息
        /// </summary>
        /// <param name="iSelf">自身Property</param>
        /// <returns>true:OK; false:NG;</returns>
        protected override bool InitSerializedProperties(SerializedProperty iSelf)
        {
            if (!base.InitSerializedProperties(iSelf)) return false;
            iSelf.isExpanded = true;

            VersionProperty = FindSerializedProperty("version");
            if (null == VersionProperty)
            {
                Error("InitSerializedProperties():There is no property named version in self serializedProperty!");
                return false;
            }
            
            CreateProperty = FindSerializedProperty("createTime");
            if (null == CreateProperty)
            {
                Error("InitSerializedProperties():There is no property named createTime in self serializedProperty!");
                return false;
            }
            
            UpdateProperty = FindSerializedProperty("updateTime");
            if (null == UpdateProperty)
            {
                Error("InitSerializedProperties():There is no property named updateTime in self serializedProperty!");
                return false;
            }
            
            return true;
        }
        
#endregion

#region Contents

        private GUIContent _headerContent = null;
        
        // 静态文件
        private GUIContent _staticCaption = null;
        private GUIContent _staticText = null;
        
        // 路径
        private GUIContent _pathCaption = null;
        private GUIContent _pathText = null;

        /// <summary>
        /// 初始化GUIContent
        /// </summary>
        protected override void InitContents()
        {
            base.InitContents();
            
            _headerContent = UtilsGUIEx.CreateGuiContentWithIcon("一般", EditorConst.IconGeneral);
            
            // 静态文件
            _staticCaption = UtilsGUIEx.CreateGuiContent("静态文件", "动态文件的话，会走热更逻辑，第一次读取该文件后，会自动导入热更目录下对应的数据信息");
            _staticText = UtilsGUIEx.CreateGuiContent($"{Static}");
            
            // 路径
            _pathCaption = UtilsGUIEx.CreateGuiContent("路径");
            _pathText = UtilsGUIEx.CreateGuiContent(Path);
        }

#endregion

#region Styles

        /// <summary>
        /// 初始化风格
        /// </summary>
        protected override void InitStyles() {}

#endregion
        
#region Draw

        /// <summary>
        /// 绘制自身
        /// </summary>
        /// <param name="iRect">绘制区域</param>
        /// <param name="iEvent">Event</param>
        /// <param name="iSelf">自身Property</param>
        protected override Rect DrawSelf(Rect iRect, Event iEvent, SerializedProperty iSelf)
        {
            var displayRect = iRect;

            var bgRect = UtilsGUIEx.DrawGenericBg(displayRect, iEvent);
            
            var titleRect = bgRect;
            titleRect.xMin += HorizontalSpacing;
            titleRect.xMax -= HorizontalSpacing;
            titleRect.y += VerticalSpacing;
            titleRect.height = HeaderHeight;

            var titleRectTmp = titleRect;
            titleRectTmp.xMin = bgRect.xMin + LabelIntent;
            titleRectTmp = UtilsGUIEx.DrawLabel(titleRectTmp, iEvent, _headerContent);

            var bodyBgRect = titleRect;
            bodyBgRect.yMin = titleRect.yMax;
            bodyBgRect.yMax = bgRect.yMax - VerticalSpacing;
            bodyBgRect = UtilsGUIEx.DrawGenericBg(bodyBgRect, iEvent);
            
            var dragMarkRect = bodyBgRect;
            dragMarkRect.y = bodyBgRect.yMin + VerticalSpacing;
            dragMarkRect.width = DragMarkWidth;
            dragMarkRect = UtilsGUIEx.DrawDragMark(dragMarkRect, iEvent);

            bodyBgRect.xMin = dragMarkRect.xMax + HorizontalSpacing;
            bodyBgRect.xMax -= HorizontalSpacing;
            bodyBgRect.yMin += VerticalSpacing;
            bodyBgRect.yMax -= VerticalSpacing;
            bodyBgRect = UtilsGUIEx.DrawGenericBg(bodyBgRect, iEvent);

            // 版本号
            var versionRect = bodyBgRect;
            if (null != VersionProperty)
            {
                versionRect.xMax -= HorizontalSpacing;
                versionRect.y = bodyBgRect.yMin + VerticalSpacing;
                versionRect.height = GetPropertiesTotalHeight(VersionProperty, GUIContent.none);
                versionRect = DrawVersion(versionRect, iEvent, VersionProperty);
            }
            
            // 静态标志位
            var staticBgRect = bodyBgRect;
            staticBgRect.xMin += HorizontalSpacing;
            staticBgRect.xMax -= HorizontalSpacing;
            staticBgRect.height = SingleLineHeight + VerticalSpacing;
            staticBgRect.y = versionRect.yMax + 2;
            staticBgRect = UtilsGUIEx.DrawGenericBg(staticBgRect, iEvent);
            
            var staticRect = staticBgRect;
            staticRect.xMin += LabelIntent;
            staticRect.xMax -= HorizontalSpacing;
            staticRect.y += 1;
            staticRect = UtilsGUIEx.DrawLabel(staticRect, iEvent, _staticCaption, _staticText);
            
            // 路径
            var pathBgRect = staticBgRect;
            pathBgRect.y = staticBgRect.yMax + 1;
            pathBgRect = UtilsGUIEx.DrawGenericBg(pathBgRect, iEvent);

            var pathRect = pathBgRect;
            pathRect.xMin += LabelIntent;
            pathRect.xMax -= HorizontalSpacing;
            pathRect.y += 1;
            pathRect = UtilsGUIEx.DrawLabel(pathRect, iEvent, _pathCaption, _pathText);
            
            // 创建日期
            var createRect = bodyBgRect;
            if (null != CreateProperty)
            {
                createRect.xMin += HorizontalSpacing;
                createRect.xMax -= HorizontalSpacing;
                createRect.y = pathRect.yMax + 1;
                createRect.height = GetPropertiesTotalHeight(CreateProperty, UtilsGUIEx.DefaultContent); 
                createRect = DrawDateTime(createRect, iEvent, CreateProperty);
            }
            
            // 更新日期
            var updateRect = bodyBgRect;
            if (null != UpdateProperty)
            {
                updateRect.xMin += HorizontalSpacing;
                updateRect.xMax -= HorizontalSpacing;
                updateRect.y = createRect.yMax + 1;
                updateRect.height = GetPropertiesTotalHeight(UpdateProperty, UtilsGUIEx.DefaultContent); 
                updateRect = DrawDateTime(updateRect, iEvent, UpdateProperty);
            }
            
            return displayRect;
        }

        /// <summary>
        /// 绘制版本信息
        /// </summary>
        /// <param name="iRect">绘制区域</param>
        /// <param name="iEvent">Event</param>
        /// <param name="iSelf">自身Property</param>
        private Rect DrawVersion(Rect iRect, Event iEvent, SerializedProperty iSelf)
        {
            var displayRect = iRect;
            if (null == iSelf) return displayRect;

            var bgRect = displayRect;
            bgRect.xMin += HorizontalSpacing;
            bgRect = DrawGenericBg(bgRect, iEvent);

            var versionRect = bgRect;
            versionRect.xMax -= HorizontalSpacing;
            versionRect.yMin += 1;
            versionRect.yMax -= 1;
            versionRect.y -= 2;
            
            EditorGUI.PropertyField(versionRect, iSelf);
            return displayRect;
        }

        /// <summary>
        /// 绘制日期
        /// </summary>
        /// <param name="iRect">绘制区域</param>
        /// <param name="iEvent">Event</param>
        /// <param name="iSelf">自身Property</param>
        private Rect DrawDateTime(Rect iRect, Event iEvent, SerializedProperty iSelf)
        {
            var displayRect = iRect;
            if (null == iSelf) return displayRect;

            var bgRect = DrawGenericBg(displayRect, iEvent);
            
            var dateTimeRect = bgRect;
            //dateTimeRect.xMin += HorizontalSpacing;
            dateTimeRect.xMax -= HorizontalSpacing;
            dateTimeRect.yMin += 1;
            dateTimeRect.yMax -= 1;
            dateTimeRect.y -= 1;
            
            EditorGUI.PropertyField(dateTimeRect, iSelf);
            return displayRect;
        }
        
#endregion
        
    }
}
